<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  class Base_Model extends CI_Model {
       protected $table_name = ''; // require
       protected $field_prefix;
       protected $insert_id;
       protected $primary_key = ''; //required
       protected $select_fields = '*';
       protected $num_rows = 0;
       protected $affected_rows = 0;
       protected $last_query = '';
       protected $error_msg = array();
       
       //validate
        protected  $validation_errors;
        protected  $validation_messages;
        protected  $rules_config;
        protected $error_delimiters;
        //$error_delimiters like '<p class="validate_error" style="color:red">,</p>'
        
       
       public function __construct() {
           parent::__construct();
           $this->load->database();
           $this->load->library('form_validation');
           $this->validation_errors = array();
           $this->validation_messages = array();
           $this->rules_config = array();
       }
               
       public function init($parame){
           foreach ($parame as $key => $val) {
               if (isset($this->$key)) {
                    $this->$key = $val;
               }
           }
           $this->check_error();
       }
       
        public function get($limit = NULL, $offset = NULL, $sort = NULL, $search = NULL)
        {
            if ($limit !== NULL) $limit = (int) $limit;
            if ($offset !== NULL) $offset = (int) $offset;
            if (is_array($sort)) {
                foreach ($sort as $field => $order) {
                    $this->db->order_by($this->field_prefix . $field, $order);
                }
            }
            if (is_array($search)) {
                foreach ($search as $field => $match) {
                    $this->db->like($this->field_prefix . $field, $match);
                }
            }
            $this->db->select($this->select_fields);
            $query = $this->db->get($this->table_name, $limit, $offset);
            $this->last_query = $this->db->last_query();
            $this->num_rows = $this->_num_rows($search);
            return ($limit == 1) ? $query->row() : $query->result();
        }
        
        public function insert($data = array())
        {
            if (is_array($data)) {
                $this->db->insert($this->table_name, $data);
                $this->insert_id = $this->db->insert_id();
                $this->_optimize();
            }
        }
    
        public function update($id = 0, $data = array())
        {
            $id = (int) $id;
            if ($id && is_array($data)) {
                $this->db->where($this->primary_key, $id);
                $this->db->update($this->table_name, $data); 
                $this->_optimize();
            }
        }

        public function delete($id = 0)
        {
            $id = (int) $id;
            if ($id) {
                $this->db->where($this->primary_key, $id);
                $this->db->delete($this->table_name); 
                $this->_optimize();
            }
        }

        private function _num_rows($search = NULL)
        {
            if ($search !== NULL) {
                foreach ($search as $field => $match) {
                    $this->db->like($this->field_prefix . $field, $match);
                }
                return $this->db->count_all_results($this->table_name);
            }
            return $this->db->count_all($this->table_name);
        }

           private function _optimize()
            {
                 $this->last_query = $this->db->last_query();
                 $this->affected_rows = $this->db->affected_rows();
                 $this->load->dbutil();
                 $this->dbutil->optimize_table($this->table_name);
            }
       
       protected function check_error(){
           if ($this->table_name == '') {
              $this->set_error('table_name_required');
           }
           if ($this->primary_key == '') {
                $this->set_error('primary_key_required');
           }
           if (count($this->error_msg) > 0) {
                $error_str = implode('<br/>',$this->error_msg);
                die(__CLASS__.'<br/>'.$error_str);
           }
       }
       
       protected function set_error($msg)
       {
            if (is_array($msg)) {
                foreach ($msg as $val) {
                    $this->error_msg[] = $val;
                }
            } else {
                $this->error_msg[] = $msg;;
            }
        }
        
        //validate
        public function set_messages($messagesArr){
            $this->validation_messages = $messagesArr;
            foreach ($messagesArr as $message) {
                 $this->form_validation->set_message($message['rule'],$message['message']);
            }
        }
        public function set_error_delimiters($error_delimiters) {
            // $error_delimiters like '<p class="validate_error" style="color:red">','</p>'
            $arr = explode(',',$error_delimiters);
            $this->form_validation->set_error_delimiters($arr[0],$arr[1]);
        }
        public function base_validate(){
            $this->form_validation->set_rules($this->rules_config); 
            $run = $this->form_validation->run();
            $this->validation_errors = validation_errors();
            return $run;
        }
        public function set_rules_config($rules_config){
            $this->rules_config = $rules_config;
        }
       
   }
?>
